#include <iostream>
#include <unistd.h>
#include <pthread.h>

using namespace std;

int cnt = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *Count(void *args)
{
    pthread_detach(pthread_self());
    uint64_t number = (uint64_t)args;
    
     cout << "ptread: " << number <<" create success"<<endl;
    while (true)
    {
        pthread_mutex_lock(&mutex);
        //为什么要让一个线程去休眠？一定是临界资源不就绪，临界资源也有状态
        //如何知晓临界资源是否就绪？自己判断（判断是访问临界资源），判断必须在加锁之后
        pthread_cond_wait(&cond,&mutex);          
        //为什么在这里
        //1. pthread_cond_wait 让进程等待的时候，会自动释放锁
        cout << "ptread: " << number <<", cnt: "<<cnt++<< endl;
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    for (uint64_t i = 0; i < 7; i++)
    {
        pthread_t tid;
        pthread_create(&tid, nullptr, Count, (void *)i);
        usleep(10000);
    }
    sleep(3);
    cout<<"main thread ctrl begin"<<endl;

    while (true)
    {
        sleep(1);
        // pthread_cond_signal(&cond);//唤醒在cond的等待队列中等待的一个线程，默认都是第一个
         pthread_cond_broadcast(&cond);//唤醒所有的线程
        cout<<"signal one thread..."<<endl;
    }
    return 0;
}

// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
//     while (true)
//     {
//         {//借用临时对象的生命周期，实现自动上锁解锁
//             LockGuard lockgard(&lock); // 临时的LockGuard对象，RAII风格的锁！
//             if (tickets > 0)
//             {
//                 usleep(1000);
//                 printf("who=%s, get a ticket: %d\n", name, tickets);
//                 tickets--;
//             }
//             else
//             {
//                 break;
//             }
//         }//在此过后，临时对象生命周期结束，自动解锁

//         usleep(13); // 抢到票之后，多线程还要执行得到票之后的后续动作，usleep模拟
//     }
//     printf("%s....quit\n", name);

//     return nullptr;
// }